{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a20c4e38",
   "metadata": {},
   "source": [
    "# ConversationBufferWindowMemory\n",
    "\n",
    "`ConversationBufferWindowMemory` keeps a list of the interactions of the conversation over time. It only uses the last K interactions. This can be useful for keeping a sliding window of the most recent interactions, so the buffer does not get too large\n",
    "\n",
    "Let's first explore the basic functionality of this type of memory."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "1196da3f",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.memory import ConversationBufferWindowMemory"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "2dac7769",
   "metadata": {},
   "outputs": [],
   "source": [
    "memory = ConversationBufferWindowMemory( k=1)\n",
    "memory.save_context({\"input\": \"hi\"}, {\"ouput\": \"whats up\"})\n",
    "memory.save_context({\"input\": \"not much you\"}, {\"ouput\": \"not much\"})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "0c034a90",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'history': 'Human: not much you\\nAI: not much'}"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "memory.load_memory_variables({})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8c5cce1d",
   "metadata": {},
   "source": [
    "We can also get the history as a list of messages (this is useful if you are using this with a chat model)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "9b15b427",
   "metadata": {},
   "outputs": [],
   "source": [
    "memory = ConversationBufferWindowMemory( k=1, return_messages=True)\n",
    "memory.save_context({\"input\": \"hi\"}, {\"ouput\": \"whats up\"})\n",
    "memory.save_context({\"input\": \"not much you\"}, {\"ouput\": \"not much\"})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "3bb47191",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'history': [HumanMessage(content='not much you', additional_kwargs={}),\n",
       "  AIMessage(content='not much', additional_kwargs={})]}"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "memory.load_memory_variables({})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a95af04c",
   "metadata": {},
   "source": [
    "## Using in a chain\n",
    "Let's walk through an example, again setting `verbose=True` so we can see the prompt."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "0b9da4cd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n",
      "\n",
      "Current conversation:\n",
      "\n",
      "Human: Hi, what's up?\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "\" Hi there! I'm doing great. I'm currently helping a customer with a technical issue. How about you?\""
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain.llms import OpenAI\n",
    "from langchain.chains import ConversationChain\n",
    "conversation_with_summary = ConversationChain(\n",
    "    llm=OpenAI(temperature=0), \n",
    "    # We set a low k=2, to only keep the last 2 interactions in memory\n",
    "    memory=ConversationBufferWindowMemory(k=2), \n",
    "    verbose=True\n",
    ")\n",
    "conversation_with_summary.predict(input=\"Hi, what's up?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "90f73431",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n",
      "\n",
      "Current conversation:\n",
      "Human: Hi, what's up?\n",
      "AI:  Hi there! I'm doing great. I'm currently helping a customer with a technical issue. How about you?\n",
      "Human: What's their issues?\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "\" The customer is having trouble connecting to their Wi-Fi network. I'm helping them troubleshoot the issue and get them connected.\""
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation_with_summary.predict(input=\"What's their issues?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "cbb499e7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n",
      "\n",
      "Current conversation:\n",
      "Human: Hi, what's up?\n",
      "AI:  Hi there! I'm doing great. I'm currently helping a customer with a technical issue. How about you?\n",
      "Human: What's their issues?\n",
      "AI:  The customer is having trouble connecting to their Wi-Fi network. I'm helping them troubleshoot the issue and get them connected.\n",
      "Human: Is it going well?\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "\" Yes, it's going well so far. We've already identified the problem and are now working on a solution.\""
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "conversation_with_summary.predict(input=\"Is it going well?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "0d209cfe",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n",
      "Prompt after formatting:\n",
      "\u001b[32;1m\u001b[1;3mThe following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.\n",
      "\n",
      "Current conversation:\n",
      "Human: What's their issues?\n",
      "AI:  The customer is having trouble connecting to their Wi-Fi network. I'm helping them troubleshoot the issue and get them connected.\n",
      "Human: Is it going well?\n",
      "AI:  Yes, it's going well so far. We've already identified the problem and are now working on a solution.\n",
      "Human: What's the solution?\n",
      "AI:\u001b[0m\n",
      "\n",
      "\u001b[1m> Finished chain.\u001b[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "\" The solution is to reset the router and reconfigure the settings. We're currently in the process of doing that.\""
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Notice here that the first interaction does not appear.\n",
    "conversation_with_summary.predict(input=\"What's the solution?\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8c09a239",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
